#include "stdafx.h"
#include "CppUnitTest.h"

#include <MallaControl.h>


using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace TPtests
{
	TEST_CLASS(MallaTest) 
	{
	public:
		TEST_METHOD(TestMallaCrear){
			// Arrange
			std::vector< glm::vec3 > v1;
			v1.push_back( glm::vec3(1.0f, 2.0f, 3.0f) );
			v1.push_back( glm::vec3(4.0f, 5.0f, 6.0f) );
			v1.push_back( glm::vec3(7.0f, 8.0f, 9.0f) );

			std::vector< glm::vec3 > v2;
			v2.push_back( glm::vec3(10.0f, 11.0f, 12.0f) );
			v2.push_back( glm::vec3(13.0f, 14.0f, 15.0f) );
			v2.push_back( glm::vec3(16.0f, 17.0f, 18.0f) );

			// Act
			MallaControl mc(3);
			mc.addCurvaControl( v1 );
			mc.addCurvaControl( v2 );

			glm::vec3 puntoV2_1 = mc.get(1, 1);

			// Assert
			Assert::AreEqual( v2[1].x, puntoV2_1.x, L"No coincide X" );
			Assert::AreEqual( v2[1].y, puntoV2_1.y, L"No coincide Y" );
			Assert::AreEqual( v2[1].z, puntoV2_1.z, L"No coincide Z" );
		}


		TEST_METHOD(TestInsuficientesPuntos_1){
			Assert::ExpectException< std::invalid_argument, void>([](){
				// Arrange
				std::vector< glm::vec3 > v1;
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				// Act
				MallaControl mc(4);
				mc.addCurvaControl( v1 );
			}, L"No arrojo una exception por exceso de puntos");
		}


		TEST_METHOD(TestInsuficientesPuntos_2){
			Assert::ExpectException< std::invalid_argument, void>([](){
				// Arrange
				std::vector< glm::vec3 > v1;
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(7.0f, 8.0f, 9.0f) );

				// Act
				MallaControl mc(5);
				mc.addCurvaControl( v1 );
			}, L"No arrojo una exception por falta de puntos");
		}


		TEST_METHOD(TestFueraDeRango_1){
			Assert::ExpectException< std::range_error, void>([](){
				// Arrange
				std::vector< glm::vec3 > v1;
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				std::vector< glm::vec3 > v2;
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				// Act
				MallaControl mc(2);
				mc.addCurvaControl( v1 );
				mc.addCurvaControl( v2 );

				// Se pide un punto fuera del rango
				glm::vec3 punto = mc.get( v1.size() +1, v2.size() +1 );
			}, L"No arrojo una exception de fuera de rango 1");
		}

		TEST_METHOD(TestFueraDeRango_2){
			Assert::ExpectException< std::range_error, void>([](){
				// Arrange
				std::vector< glm::vec3 > v1;
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				std::vector< glm::vec3 > v2;
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				// Act
				MallaControl mc(2);
				mc.addCurvaControl( v1 );
				mc.addCurvaControl( v2 );

				// Se pide un punto fuera del rango en "X"
				glm::vec3 punto = mc.get( v1.size() +1, v2.size() -1 );
			}, L"No arrojo una exception de fuera de rango 2");
		}

		TEST_METHOD(TestFueraDeRango_3){
			Assert::ExpectException< std::range_error, void>([](){
				// Arrange
				std::vector< glm::vec3 > v1;
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v1.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				std::vector< glm::vec3 > v2;
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );
				v2.push_back( glm::vec3(1.0f, 1.0f, 1.0f) );

				// Act
				MallaControl mc(2);
				mc.addCurvaControl( v1 );
				mc.addCurvaControl( v2 );

				// Se pide un punto fuera del rango en "Y"
				glm::vec3 punto = mc.get( v1.size() -1, v2.size() +1 );
			}, L"No arrojo una exception de fuera de rango 3");
		}

	};
}

